let ScheduleService = require('./ScheduleService');
let Mongodb = require('../../database/mongodb');
let request = require('request');
let CICI = require('../../routes/message/cici');
let Email = require('../../routes/message/email')

/**
 * 系统调度任务，60秒执行一次.
 */
class SystemSchedule extends ScheduleService {

  initRule () {
    this.rule.second = [0, 60];
  }

  runTask () {
    console.log('进入调度任务')
    onceRemind()
    minRemind()
    dayRemind()
    weekRemind()
    douleWeekRemind()
    monthRemind()
  }
}

/**
 * 执行调度任务.
 */
function exec (task) {
  return new Promise((resolve, reject) => {
    if (task.taskUrl) {
      get(task.taskUrl).then((data) => {
        saveHistory(task, true)
        if (task.smessage) {
          sendMessage(task, task.smessage)
          resolve()
        }
      }, (err) => {
        saveHistory(task, false)
        if (task.emessage) {
          sendMessage(task, task.emessage)
          resolve()
        }
      })
    } else {
      saveHistory(task, undefined)
      if (task.message) {
        sendMessage(task, task.message)
      }
      resolve()
    }
  
    if (task.callbackUrl) {
      get(task.callbackUrl)
    }
  })
}

function saveHistory (task, flag) {
  let data = {
    taskId: task._id,
    businessId: task.businessId,
    businessType: task.businessType,
    name: task.name,
    exTime: new Date(),
    result: flag
  }
  Mongodb.save('history_remind', data, function (err, docs) {
    if (err) {
      console.log(err)
    }
  })
}

/**
 * 状态更新为已完成.
 * @param {*} task
 */
function deleteTask(task) {
  var where = {
    _id: task._id
  };
  var tbName = 'remind'

  var fields = {
    state: '2'
  };
  Mongodb.update(tbName, where, fields, function (err, docs) {
    if (err) {
      console.log(err)
    }
  });
}

function get(url) {
  return new Promise((resolve, reject) => {
    request.get({
      url: url,
      timeout: 3000
    }, (error, response, body) => {
      if (!error && response.statusCode == 200) {
        resolve(body)
      } else {
        reject(error)
        console.log(error)
      }
    })
  })
}

/**
 * 处理单次提醒任务.
 */
function onceRemind() {
  // console.log('开始处理单次提醒任务')
  let curDate = new Date()
  let queryCondition = {
    "state": "0",
    "remind.type": "ONCE",
    "remind.remindTime": { '$lte': new Date(new Date().getTime() + 1000 * 60 * 1).toISOString(), '$gte': new Date(new Date().getTime() - 1000 * 60 * 1).toISOString() }
  }
  Mongodb.find('remind', queryCondition, {}, {}, function(err, docs){
    if (docs && (docs.length > 0)) {
      console.log('单次提醒任务：' + docs.length + '个')
      for (let index = 0; index < docs.length; index++) {
        const task = docs[index]
        if ((curDate.getDate() === new Date(task.remind.remindTime).getDate()) &&
            (curDate.getHours() === new Date(task.remind.remindTime).getHours()) &&
            (curDate.getMinutes() === new Date(task.remind.remindTime).getMinutes())) {
          exec(task).then(() => {
            deleteTask(task)
          })
        }
      }
    } else {
      // console.log('无单次任务退出')
    }
  })
}

/**
 * 处理按分钟任务.
 */
function minRemind() {
  // console.log('开始处理按分提醒任务')
  let curDate = new Date()
  let queryCondition = {
    "state": "0",
    "remind.type": "MIN",
    "remind.beginDate": { '$lte': curDate.toISOString() },
    "remind.endDate": { '$gte': curDate.toISOString() }
  }
  Mongodb.find('remind', queryCondition, {}, {}, function(err, docs){
    if (docs && (docs.length > 0)) {
      console.log('按分提醒任务：' + docs.length + '个')
      for (let index = 0; index < docs.length; index++) {
        const task = docs[index]
        if (curDate.getMinutes() % Number(task.remind.offset) === 0) {
          exec(task).then(() => {
            // 如果下次执行时间大于截止时间则删除任务
            if ((curDate.getTime() + Number(task.remind.offset) * 60 * 1000) > new Date(task.remind.endDate).getTime()) {
              deleteTask(task)
            }
          })
        }
      }
    } else {
      // console.log('无按分任务退出')
    }
  })
}

/**
 * 处理按天任务.
 */
function dayRemind() {
  // console.log('开始处理按天提醒任务')
  let curDate = new Date()
  let queryCondition = {
    "state": "0",
    "remind.type": "DAY",
    "remind.remindTime": { '$lte': curDate.toISOString() },
    "remind.endDate": { '$gte': curDate.toISOString() }
  }
  Mongodb.find('remind', queryCondition, {}, {}, function(err, docs){
    if (docs && (docs.length > 0)) {
      console.log('按天提醒任务：' + docs.length + '个')
      for (let index = 0; index < docs.length; index++) {
        const task = docs[index]
        // 小时和分钟相同则提醒
        if ((curDate.getHours() === new Date(task.remind.remindTime).getHours()) && (curDate.getMinutes() === new Date(task.remind.remindTime).getMinutes())) {
          exec(task).then(() => {
            // 如果下次执行时间大于截止时间则删除任务
            if ((curDate.getTime() + 24 * 60 * 60 * 1000) > new Date(task.remind.endDate).getTime()) {
              deleteTask(task)
            }
          })
        }
      }
    } else {
      // console.log('无按天任务退出')
    }
  })
}

/**
 * 处理按周任务.
 */
function weekRemind() {
  // console.log('开始处理按周提醒任务')
  let curDate = new Date()
  let queryCondition = {
    "state": "0",
    "remind.type": "WEEK",
    "remind.remindTime": { '$lte': curDate.toISOString() },
    "remind.endDate": { '$gte': curDate.toISOString() }
  }
  Mongodb.find('remind', queryCondition, {}, {}, function(err, docs){
    if (docs && (docs.length > 0)) {
      console.log('按周提醒任务：' + docs.length + '个')
      for (let index = 0; index < docs.length; index++) {
        const task = docs[index]
        // 星期、小时和分钟相同则提醒
        if ((curDate.getDay() === new Date(task.remind.remindTime).getDay()) &&
            (curDate.getHours() === new Date(task.remind.remindTime).getHours()) &&
            (curDate.getMinutes() === new Date(task.remind.remindTime).getMinutes())) {
          exec(task).then(() => {
            // 如果下次执行时间大于截止时间则删除任务
            if ((curDate.getTime() + 7 * 24 * 60 * 60 * 1000) > new Date(task.remind.endDate).getTime()) {
              deleteTask(task)
            }
          })
        }
      }
    } else {
      // console.log('无按周任务退出')
    }
  })
}

/**
 * 处理按双周任务.
 */
 function douleWeekRemind() {
  // console.log('开始处理按双周提醒任务')
  let curDate = new Date()
  let queryCondition = {
    "state": "0",
    "remind.type": "DOUBLE_WEEK",
    "remind.remindTime": { '$lte': curDate.toISOString() },
    "remind.endDate": { '$gte': curDate.toISOString() }
  }
  Mongodb.find('remind', queryCondition, {}, {}, function(err, docs){
    if (docs && (docs.length > 0)) {
      console.log('按双周提醒任务：' + docs.length + '个')
      for (let index = 0; index < docs.length; index++) {
        const task = docs[index]
        // 从开始时间计算，双周提醒
        let flag = Math.round((curDate.getTime() - new Date(task.remind.remindTime).getTime()) / 1000 / 60 / 60 / 24 / 7) % 2 === 0
        if (flag && (curDate.getDay() === new Date(task.remind.remindTime).getDay()) &&
            (curDate.getHours() === new Date(task.remind.remindTime).getHours()) &&
            (curDate.getMinutes() === new Date(task.remind.remindTime).getMinutes())) {
          exec(task).then(() => {
            // 如果下次执行时间大于截止时间则删除任务
            if ((curDate.getTime() + 14 * 24 * 60 * 60 * 1000) > new Date(task.remind.endDate).getTime()) {
              deleteTask(task)
            }
          })
        }
      }
    } else {
      // console.log('无按双周任务退出')
    }
  })
}

/**
 * 处理按月任务.
 */
function monthRemind() {
  // console.log('开始处理按月提醒任务')
  let curDate = new Date()
  let queryCondition = {
    "state": "0",
    "remind.type": "MONTH",
    "remind.remindTime": { '$lte': curDate.toISOString() },
    "remind.endDate": { '$gte': curDate.toISOString() }
  }
  Mongodb.find('remind', queryCondition, {}, {}, function(err, docs){
    if (docs && (docs.length > 0)) {
      console.log('按月提醒任务：' + docs.length + '个')
      for (let index = 0; index < docs.length; index++) {
        const task = docs[index]
        // 日期、小时和分钟相同则提醒
        if ((curDate.getDate() === new Date(task.remind.remindTime).getDate()) &&
            (curDate.getHours() === new Date(task.remind.remindTime).getHours()) &&
            (curDate.getMinutes() === new Date(task.remind.remindTime).getMinutes())) {
          exec(task).then(() => {
            // 如果下次执行时间大于截止时间则删除任务
            curDate.setMonth(curDate.getMonth() + 1)
            if (curDate.getTime() > new Date(task.remind.endDate).getTime()) {
              deleteTask(task)
            }
          })
        }
      }
    } else {
      // console.log('无按月任务退出')
    }
  })
}

function sendMessage (task, content) {
  if (task.remind.cici) {
    for (let i = 0; i < task.remindUsers.length; i++) {
      CICI.remindMess(task.remindUsers[i], content, task.linkUrl | 'https://test/works/#/dashboard/board', () => {});
    }
  }
  if (task.remind.email) {
    let mailObj = {
      toEmail: task.remindUsers.join(';'),
      ccEmail: 'sachuangwei@sachuangwei.com',
      subject: '【Easywork任务提醒】' + task.name,
      content: content
    }
    Email.sendMail(mailObj, () => {})
  }
}

module.exports = new SystemSchedule()
